/*
 * test_googleprotocolbuffer.h
 *
 *  Created on: 2014. 7. 4.
 *      Author: jjaehuny
 */

#ifndef TEST_GOOGLEPROTOCOLBUFFER_H_
#define TEST_GOOGLEPROTOCOLBUFFER_H_

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <gtest/gtest.h>

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/text_format.h>

#include <GoogleProtocolBuffer/message/sample.pb.h>

#include <Framework/Network/Packet.h>

class test_googleprotocolbuffer : public testing::Test
{
public:
	class Dummy
	{
	public:
		Dummy() {}
		~Dummy() {}
	};

public:
	// Sets up the test fixture.
	virtual void SetUp() {}

	// Tears down the test fixture.
	virtual void TearDown() {}
};

TEST_F(test_googleprotocolbuffer, test_googleprotocolbuffer)
{
	//GOOGLE_PROTOBUF_VERIFY_VERSION;

	// Message 객체에 값 세팅
	tutorial::Person src_person;
	src_person.set_id(41);
	src_person.set_name("jjaehuny");
	src_person.set_email("jjaehuny@gamevil.com");

	tutorial::Person::PhoneNumber* phone0 = src_person.add_phone();
	phone0->set_number("010-2090-0518");
	phone0->set_type(tutorial::Person_PhoneType_MOBILE);

	tutorial::Person::PhoneNumber* phone1 = src_person.add_phone();
	phone1->set_number("031-1234-5678");
	phone1->set_type(tutorial::Person_PhoneType_HOME);

	// 미리 생성해야 하는 버퍼의 길이를 알아내어 버퍼할당
	int bufSize = src_person.ByteSize();
	//char* outputBuf = new char[bufSize];

	::Framework::Network::Packet clsPacket;
	clsPacket.resize(bufSize);

	// 버퍼에 직렬화
	google::protobuf::io::ArrayOutputStream os(clsPacket.BodyBuffer(), bufSize);
	src_person.SerializeToZeroCopyStream(&os);

	// 버퍼에서 역직렬화
	google::protobuf::io::ArrayInputStream is(clsPacket.BodyBuffer(), bufSize);
	tutorial::Person dst_person0;
	dst_person0.ParseFromZeroCopyStream(&is);

	// Message 객체에서 값 가져오기
	std::string name = dst_person0.name();
	LOG(INFO) << "[name : " << name << "]";
	int id = dst_person0.id();
	LOG(INFO) << "[id : " << id << "]";
	for (int i=0;i<dst_person0.phone_size();++i)
	{
		const tutorial::Person_PhoneNumber& phone = dst_person0.phone(i);
		//tutorial::Person_PhoneType phone_type = phone.type();
		std::string phone_number = phone.number();
		LOG(INFO) << "[phone_number : " << phone_number << "]";
	}

	// 파일에 직렬화
	const char* test_filename = "person.txt";
	std::fstream ofs(test_filename, std::ios::out | std::ios::trunc | std::ios::binary);
	src_person.SerializeToOstream(&ofs);
	ofs.close();

	{
		// 파일에서 역직렬화
		std::fstream ifs(test_filename, std::ios::in | std::ios::binary);
		tutorial::Person dst_person1;
		dst_person1.ParseFromIstream(&ifs);
		ifs.close();


		std::string name = dst_person1.name();
		LOG(INFO) << "[name : " << name << "]";
		int id = dst_person1.id();
		LOG(INFO) << "[id : " << id << "]";
		for (int i=0;i<dst_person1.phone_size();++i)
		{
			const tutorial::Person_PhoneNumber& phone = dst_person1.phone(i);
			//tutorial::Person_PhoneType phone_type = phone.type();
			std::string phone_number = phone.number();
			LOG(INFO) << "[phone_number : " << phone_number << "]";
		}
	}

	std::string textFormatStr;
	google::protobuf::TextFormat::PrintToString(src_person, &textFormatStr);
	LOG(INFO) << textFormatStr;

	//google::protobuf::ShutdownProtobufLibrary();

}



#endif /* TEST_GOOGLEPROTOCOLBUFFER_H_ */
